#include <iostream>
#include <ripple/core/Config.h>
#include <ripple/app/main/Application.h>
#include <ripple/app/ledger/Ledger.h>
#include <ripple/basics/Log.h>
#include <ripple/core/TimeKeeper.h>
#include <ripple/rpc/impl/RPCHelpers.h>
using namespace std;

int main(int argc,char** argv){
    using namespace ripple;
    using namespace beast::severities;
    Severity thresh = kInfo;
    auto logs = std::make_unique<Logs>(thresh);
    auto config = std::make_unique<ripple::Config>();
    auto timeKeeper = make_TimeKeeper(
                logs->journal("TimeKeeper"));
    config->setup(std::string(),false,false,false);
    auto app = make_Application(
                std::move(config),
                std::move(logs),
                std::move(timeKeeper));

    if (!app->setup ())
    {
        return -1;
    }
    std::shared_ptr<Ledger> ledger;
    uint256 hash;
//FF94CA6984A806F5E339B53736ED9EC0FE21C7704CB1587D4E94D3E40D1B5FAA
    //if (hash.SetHex ("6E57DABE9705B8259AD08637E047637727B261DF46C82BEAE32E24224F3DD725"))
    if (hash.SetHex ("FF94CA6984A806F5E339B53736ED9EC0FE21C7704CB1587D4E94D3E40D1B5FAA"))
    {
        //ledger = loadByHash (hash, *app.get());
    }
    ledger = loadByIndex(25691733,*app.get());
    if (!ledger){
        std::cerr << "not found ledger"<<std::endl;
        return -1;
    }


    Json::Value result;
    AccountID accountID;
    auto jvAccepted = RPC::accountFromString (accountID, "rXzxK7wpKLZ99qwXNiy5nFQUhYxFZq3Rd", false);

    if (jvAccepted){
        std::cerr<< jvAccepted.asString()<<std::endl;
        return -1;
    }

    auto const sleAccepted = ledger->read(keylet::account(accountID));
    if (sleAccepted)
    {

        RPC::injectSLE(jvAccepted, *sleAccepted);
        result[jss::account_data] = jvAccepted;
        //std::cout<< result.toStyledString()<<std::endl;
    }

    int i=0;
    std::int64_t maxBlance=0;
    AccountID maxid;
    SHAMap const &stateMap=ledger->stateMap();
    SHAMap::const_iterator it=stateMap.begin();    
    while(it!=stateMap.end()){

        auto sle = std::make_shared<SLE>(
                    SerialIter{it->data(),
                               it->size()}, it->key());
        if(sle->getType()==LedgerEntryType::ltACCOUNT_ROOT){
            ++i;
            //bool isBreak=false;
             AccountID accountId;
            if(sle->isFieldPresent(sfAccount)){
                accountId =
                    sle->getAccountID(sfAccount);
                 std::cout<<i<<"\""<<toBase58(accountId)<<"\",";
                 //if(accountID==accountId) isBreak=true;

            }
            if(sle->isFieldPresent(sfBalance)){
                auto const balance =
                    sle->getFieldAmount(sfBalance).xrp();
                 std::cout<<balance.drops()/1000000<<std::endl;
                 if(maxBlance<balance.drops()){
                     maxBlance=balance.drops();
                     maxid=accountId;
                 }

            }
            //if(isBreak) break;
//            RPC::injectSLE(jvAccepted, *sle);
//            result[jss::account_data] = jvAccepted;
//            std::cout<< result.toStyledString()<<std::endl;
//            std::cout<<"count:"<<++i<<std::endl;
        }
        ++it;
    }
    //std::cout << "maxBlance:"<<maxBlance<<"@"<<maxid<<std::endl;
    //cout << "Hello World,I'm 李建峰"<<endl;
    return 0;
}
